﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace HYCodeBase.AsyncUtility.AsyncSupport
{
	public abstract class HalfNSquareSupport
	{
		public Dictionary<IElement, Dictionary<IElement, object>> DicResults
		{
			get
			{
				return this.m_dicResults;
			}
			private set
			{
				this.m_dicResults = value;
			}
		}

		public abstract void Calculate();

		public static HalfNSquareSupport GetOneManger(IList<IElement> inputLstElement, int? useThreadCount)
		{
			return new SplitAndAllWaitHalfNSquareSupport(inputLstElement, useThreadCount);
		}

		private IList<IElement> PrepareLstElement(IList<IElement> input)
		{
			return (from n in input
			where n != null
			select n).Distinct<IElement>().ToList<IElement>();
		}

		private int GetMachineCoreNumber()
		{
			return Environment.ProcessorCount;
		}

		protected void CalculateByOneRow(object inputIndex)
		{
			int useIndex = (int)inputIndex;
			this.CalculateByOneRow(useIndex);
		}

		protected void CalculateByOneRow(int useIndex)
		{
			IElement element = this.m_lstUseElment[useIndex];
			Dictionary<IElement, object> dictionary = new Dictionary<IElement, object>();
			object obj = null;
			for (int i = useIndex + 1; i < this.m_lstUseElment.Count; i++)
			{
				try
				{
					obj = element.Interactive(this.m_lstUseElment[i]);
				}
				catch (Exception)
				{
					obj = null;
				}
				if (obj != null)
				{
					dictionary.Add(this.m_lstUseElment[i], obj);
				}
			}
			this.DicResults[element] = dictionary;
		}

		protected HalfNSquareSupport(IList<IElement> inputLstElement, int? useThreadCount)
		{
			this.m_lstInputElement = inputLstElement;
			this.m_lstUseElment = this.PrepareLstElement(this.m_lstInputElement);
			if (useThreadCount == null)
			{
				this.m_nUseCoreNumber = this.GetMachineCoreNumber();
			}
			else
			{
				this.m_nUseCoreNumber = useThreadCount.Value;
			}
            //this.m_dicResults = this.m_lstUseElment.ToDictionary((IElement k) => k, (IElement k) => null);
		}

		protected IList<IElement> m_lstInputElement;

		protected IList<IElement> m_lstUseElment;

		protected int m_nUseCoreNumber;

		protected Dictionary<IElement, Dictionary<IElement, object>> m_dicResults;
	}
}
